#include <linux/module.h>

#include <linux/fs.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/kernel.h>
#include <linux/major.h>
#include <linux/mutex.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/stat.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/tty.h>
#include <linux/kmod.h>
#include <linux/gfp.h>

#define Major 200
#define Min(a, b) (a < b ? a:b)

char kernelbuffer[1024] = "123";

int chrdevbase_open (struct inode *node, struct file *file)
{
    printk("chrdevbase open \r\n");
    return 0;
}
ssize_t chrdevbase_read (struct file *file, char __user *buf, size_t size, loff_t *offset)
{
    int ret;
    // printk("chrdevbase read \r\n");
    ret = __copy_to_user(buf, kernelbuffer, Min(1024, size));

    return Min(1024, size);
}
ssize_t chrdevbase_write (struct file *file, const char __user *buf, size_t size, loff_t *offset)
{
    int ret;
    ret = __copy_from_user(kernelbuffer, buf, Min(1024, size));
    printk("recevie data: %s\r\n", kernelbuffer);

    return Min(1024, size);
}
int chrdevbase_release (struct inode *node, struct file *file)
{
    // printk("chrdevbase release \r\n");
    return 0;
}

struct file_operations chrdevbase_operations = {
    .owner = THIS_MODULE,
    .open = chrdevbase_open,
    .read = chrdevbase_read,
    .write = chrdevbase_write,
    .release = chrdevbase_release,
};

static int __init chrdevbase_init(void)
{
    int ret;
    printk("chrdevbase init \r\n");
    /* 注册字符设备驱动 */
    ret = register_chrdev(Major, "chrdevbase", &chrdevbase_operations);
    if(ret < 0)
    {
        printk("chrdevbase init faild\r\n");
        return 0;
    }

    return 0;
}

static void __exit chrdevbase_exit(void)
{
    printk("chrdevbase exit \r\n");
    /* 注销字符设备驱动 */
    unregister_chrdev(Major, "chrdevbase");
}

/**
 * 模块入口和出口
 */
module_init(chrdevbase_init);  // 入口
module_exit(chrdevbase_exit);  // 出口

/**
 * LICENSE 和作者信息
*/
MODULE_LICENSE("GPL");
MODULE_AUTHOR("george < g_yubo@163.com >");
